package com.indusfo.spc.service.impl;

import com.indusfo.spc.exception.GlobalException;
import com.indusfo.spc.exception.ModifyFailedException;
import com.indusfo.spc.exception.ParamsErrorException;
import com.indusfo.spc.mapper.*;
import com.indusfo.spc.pojo.*;
import com.indusfo.spc.service.MatService;
import com.indusfo.spc.vo.HintMessage;
import com.indusfo.spc.vo.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author louk
 * @date 2019/11/18 8:59
 */
@Service
public class MatServiceImpl implements MatService {

    private static final Logger logger = LoggerFactory.getLogger(MatServiceImpl.class);


    @Resource
    private MatMapper matMapper;
    @Resource
    private MatTypeMapper matTypeMapper;

    @Resource
    private UploadMapper uploadMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private DosingMapper dosingMapper;
    //查询

    /**
     * @author: louk
     * @param:
     * @Return:
     * @Description: :初始化页面默认显示树列表当中的第一个的信息
     * @date: 2019/9/4 17:21
     */

    @Override
    public JSONObject listMat(Mat mat) {

        try {
            // 获取一页显示多少行
            Integer pagesize = mat.getPagesize();
            // 获取查询第几页
            Integer pageindex = mat.getPageindex();

            // 若不为空计算从第几条开始查询
            if (pagesize != null && pageindex != null) {
                mat.setIncept(pagesize * (pageindex - 1));
            }
            // 为空进行多条的分页查询
            // 调用Mapper分页查询方法

            List<Mat> listForPage = matMapper.selectAllMat(mat);
            // 判断是否查询到数据
            if (listForPage.isEmpty()) {
                return JSONObject.oK("没有相关数据", listForPage, 0);
            }

            Integer count = matMapper.countMat(mat);
            return JSONObject.oK(listForPage, count);

        } catch (GlobalException e) {
            // 捕获异常,打印并返回数
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());
        }

    }

    // 增加或修改
    @Override
    public JSONObject insertMat(Mat mat) {

        try {
            /**
             * 新增编号名称不能重复
             */
            if (mat.getDataState() == null) {
                mat.setDataState(1);
            }
            // 没id,做新增
            // 校验传入参数
            String validateResult = validate(mat);
            if(!StringUtils.isEmpty(validateResult)){
                return JSONObject.build(JSONObject.ERROR,validateResult);
            }
            String checkNoRepeatResult = checkNoRepeat(mat);
            if(!StringUtils.isEmpty(checkNoRepeatResult)){
                return JSONObject.build(JSONObject.ERROR,checkNoRepeatResult);
            }

            Integer row = matMapper.insertSelective(mat);
            if (row == 0) {
                
                throw new ModifyFailedException("新增物料失败");
            }
            return JSONObject.oK("新增成功", row);


        } catch (GlobalException e) {
            logger.error(e.getMessage());
            return JSONObject.build(500, e.getMessage());
        }
    }

    /**
     * 更新物料信息
     *
     * @param mat
     * @return
     */
    @Override
    public JSONObject updateMat(Mat mat) {
        try {
            /**
             * 新增编号名称不能重复
             */
            if (mat.getDataState() == null) {
                mat.setDataState(1);
            }
            if (mat.getMatId() == null || "".equals(mat.getMatId())) {
                throw new ModifyFailedException("请选择物料");
            }
            String validateResult = validate(mat);
            if(!StringUtils.isEmpty(validateResult)){
                return JSONObject.build(JSONObject.ERROR,validateResult);
            }
            String checkNoRepeatResult = checkNoRepeat(mat);
            if(!StringUtils.isEmpty(checkNoRepeatResult)){
                return JSONObject.build(JSONObject.ERROR,checkNoRepeatResult);
            }
            Integer row = matMapper.updateByPrimaryKeySelective(mat);
            if (row == 0) {
                throw new ModifyFailedException("更新物料失败");
            }
            return JSONObject.oK("更新成功", row);


        } catch (GlobalException e) {
            logger.error(e.getMessage());
            return JSONObject.build(500, e.getMessage());
        }
    }

    /**
     * 删除
     *
     * @param deteMaterialXO
     * @param lDataState
     * @return
     */
    @Override
    public JSONObject deleteMat(Integer[] deteMaterialXO, Integer lDataState) {
        try {
            //1.校验
            if (deteMaterialXO == null) {
                throw new ParamsErrorException("物料信息id不能为空");
            }
            if (lDataState == null) {
                throw new ParamsErrorException("物料信息状态不能为空");
            }

            if(new Integer(2).equals(lDataState)){
                //物料 如果被任务单使用过 不能删除
                int useMatOrder = orderMapper.queryUseMat(deteMaterialXO);
                if(useMatOrder>0){
                    return JSONObject.build(JSONObject.ERROR,"所选物料已被任务单使用,无法删除");
                }
                //物料 如果被叫料信息使用过  不能删除（物料分成品和原材料）
                int useMatDosing = dosingMapper.queryUseMat(deteMaterialXO);
                if(useMatDosing>0){
                    return JSONObject.build(JSONObject.ERROR,"所选物料已被叫料信息使用,无法删除");
                }
            }

            int row = matMapper.defineMat(deteMaterialXO, lDataState);
            String msg = "";
            switch (lDataState) {
                case 1:
                    msg = "启用";
                    break;
                case 2:
                    msg = "删除";
                    break;
                case 3:
                    msg = "停用";
            }

            if (row == 0) {
                // 判断传入的数据状态参数lDataState,返回相应信息
                switch (lDataState) {
                    case 1:
                        throw new ModifyFailedException(msg + "失败");
                    case 2:
                        throw new ModifyFailedException(msg + "失败");
                    case 3:
                        throw new ModifyFailedException(msg + "失败");
                }
            }
            return JSONObject.oK(msg + "成功", row);
        } catch (GlobalException e) {
            logger.error(e.getMessage());
            return JSONObject.build(500, e.getMessage());
        }
    }

    /**
     * 高级查询
     *
     * @param materialXO
     * @return
     */
    @Override
    public JSONObject advancedQuery(Mat materialXO) {


        try {

            // 获取一页显示多少行
            Integer pagesize = materialXO.getPagesize();
            // 获取查询第几页
            Integer pageindex = materialXO.getPageindex();
            Integer lMatType = materialXO.getMatTypeId();

            // 若不为空计算从第几条开始查询
            if (pagesize != null && pageindex != null) {
                materialXO.setIncept(pagesize * (pageindex - 1));
            }
            List<Mat> materialXOS = matMapper.advancedQuery(materialXO);

            // 判断是否查询到数据
            if (materialXOS.isEmpty()) {
                return JSONObject.oK("没有相关数据", materialXOS, 0);
            }
            // 查询有多少条数据条数
            if (pagesize != null && pageindex != null) {
                Integer count = matMapper.countAdvancedQuery(materialXO);
                return JSONObject.oK(materialXOS, count);
            }
            return JSONObject.oK(materialXOS.get(0));


        } catch (GlobalException e) {
            // 捕获异常,打印并返回数
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());
        }

    }


    /**
     * 验证重复
     *
     * @param mat
     * @return
     */
    private JSONObject checkParamsNotRepeat(Mat mat) {
        try {
            // 判断不良原因类型ID是否传入
            if (mat.getMatId() == null || mat.getMatId() == 0) {
                throw new ParamsErrorException("未传入物料ID");
            } else {
                Mat check = new Mat();
                check.setMatName(mat.getMatName());
                if (mat.getMatId() != null) {
                    // 有SOP基础资料ID为更新操作,调用剔除本条记录是否有重复
                    check.setMatId(mat.getMatId());
                    int row = matMapper.countParamsNotRepeat(check);
                    if (row > 0) {
                        throw new ParamsErrorException("已存在该产品");
                    }
                } else {
                    // 无SOP基础资料ID为新增操作,调用Mapper查询所有是否有重复
                    int row = matMapper.countParamsNotRepeat(check);
                    if (row > 0) {
                        throw new ParamsErrorException("已存在该产品");
                    }
                }
                return JSONObject.oK();
            }
        } catch (GlobalException e) {
            // 捕获异常,打印并返回
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());
        }
    }

    /**
     * 判断物料编码物料名称是否重复
     *
     * @param mat
     */
    private String checkNoRepeat(Mat mat) {
        int codeRow = matMapper.countCodeNoRepeat(mat);
        if (codeRow > 0) {
            return "物料编码已存在";
        }
        return null;
        /*int nameRow = matMapper.countNameNoRepeat(mat);
        if (nameRow > 0) {
            throw new ParamsErrorException("物料名称已存在");
        }*/
    }

    /**
     * 非空判断
     *
     * @param mat
     */
    private String validate(Mat mat) {
        //物料编码
        String vcMatCode = mat.getMatCode();
        //物料名称
        String vcProjectName = mat.getMatName();
        //规格型号
        String vcModel = mat.getMatModel();
        //条码规则
        Integer vcBarrule = mat.getRuleId();
        if (StringUtils.isEmpty(vcMatCode)) {
            return "物料编码不能为空";
        }
        if(vcMatCode.getBytes().length>50){
            return "物料编码长度不能超过50";
        }
        if (StringUtils.isEmpty(vcProjectName)) {
            return "物料名称不能为空";
        }
        if(vcProjectName.getBytes().length>50){
            return "物料名称长度不能超过50";
        }
        if (StringUtils.isEmpty(vcModel)) {
            return "规格型号不能为空";
        }
        if(vcModel.getBytes().length>50){
            return "规格型号长度不能超过50";
        }
        if (vcBarrule == null) {
            return "条码规则不能为空";
        }
        //物料单位
        Integer lMatUnit = mat.getMatUnitId();
        //物料类型
        Integer lMatType = mat.getMatTypeId();
        //物料来源
//        Integer lSourceId = mat.getMatSourceId();
        if (lMatUnit == null || "".equals(lMatUnit) || new Integer(0).equals(lMatUnit)) {
            return "物料单位不能为空";
        }
        if (lMatType == null || "".equals(lMatType) || new Integer(0).equals(lMatType)) {
            return "物料类型不能为空";
        }
        /*if (lSourceId == null) {
            throw new ParamsErrorException("物料来源不能为空");
        }*/
        //成品机型id
        Integer artifactTypeId = mat.getArtifactTypeId();
        if (artifactTypeId == null || "".equals(artifactTypeId) || new Integer(0).equals(artifactTypeId)) {
            return  "成品机型不能为空";
        }
        return null;
    }

    /**
     * 检查excel字段内容
     *
     * @param mat
     * @return
     */
    @Override
    public String checkExcelContent(Mat mat,Map<String, Mat> matMap ,Map<String, Rule> ruleMap,Map<String, Datadict> matunitMap, Map<String, MatType> mtypeMap,Map<String, Datadict> artifactTypeIdNameMap  ) {
        //物料编码
        String vcMatCode = mat.getMatCode();
        //物料名称
        String vcProjectName = mat.getMatName();
        //规格型号
        String vcModel = mat.getMatModel();
        //条码规则
        String ruleName = mat.getRuleName();
        //物料名称
        String mtype = mat.getMatTypeName();
        //单位名称
        String matunit = mat.getMatUnitName();
        /*//物料来源
        String lSourceName = mat.getMatSourceName();*/
        //图号
        String figureNumber = mat.getFigureNum();
        //客户代码
        String customerCode = mat.getCustomerName();
        //单位数量
        Integer lMatUnitCount = mat.getUnitNum();
        //成品机型
        String finishedProductModeltCount = mat.getDeviceModel();
        //资源数
        Integer resourceNumber = mat.getResourceNum();
        //生产节拍
        Integer productionTakt = mat.getProductTakt();
        //干燥时间
        Integer dryingTime = mat.getDryDate();
        //保有量
        Integer inventory = mat.getInventoryNum();
        //报工数量
        Integer workNumber = mat.getFinishNum();
        //成品类型
        String artifactTypeIdName = mat.getArtifactTypeIdName();

        if (StringUtils.isEmpty(vcMatCode)) {
            return "物料编码不能为空";
        }

        if(vcMatCode.getBytes().length>50){
            return "物料编码长度不能超过50个字节,25个汉字";
        }
        if (StringUtils.isEmpty(vcProjectName)) {
            return "物料名称不能为空";
        }
        if(vcProjectName.getBytes().length>50){
            return "物料名称长度不能超过50个字节,25个汉字";
        }
        if (StringUtils.isEmpty(vcModel)) {
            return "规格型号不能为空";
        }
        if(vcModel.getBytes().length>50){
            return "规格型号长度不能超过50个字节,25个汉字";
        }
        if (StringUtils.isEmpty(ruleName)) {
            return "条码规则不能为空";
        }

        if (!ruleMap.containsKey(ruleName)) {
            return "条码规则名称书写不规范/不存在";
        } else {
            Rule rule = ruleMap.get(ruleName);
            mat.setRuleId(
                    rule.getRuleId()
            );
        }

        if (StringUtils.isEmpty(matunit)) {
            return "单位名称不能为空";
        }

        if (!matunitMap.containsKey(matunit)) {
            return "单位名称书写不规范/不存在";
        } else {
            Datadict tdatadict = matunitMap.get(matunit);
            mat.setMatUnitId(tdatadict.getItemId());
        }

        if (StringUtils.isEmpty(mtype)) {
            return "物料类别名称不能为空";
        }

        if (!mtypeMap.containsKey(mtype)) {
            return "物料类别名称书写不规范/不存在";
        } else {
            MatType mType = mtypeMap.get(mtype);
            mat.setMatTypeId(mType.getMatTypeId());
        }
        if(matMap.containsKey(mat.getMatCode())){
            return "物料编码已存在";
        }
        if (StringUtils.isEmpty(artifactTypeIdName)) {
            return "物料类型为空";
        }
        if (!artifactTypeIdNameMap.containsKey(artifactTypeIdName)) {
            return "物料类型名称填写错误/不规范";
        }
        mat.setArtifactTypeId(artifactTypeIdNameMap.get(artifactTypeIdName).getItemId());
        if (StringUtils.isEmpty(artifactTypeIdName)) {
            return "物料类型名称为空";
        }
        return null;
    }

    @Override
    public List<ExcelErrorData> checkExcelContentList(Sheet sheet, List<Mat> matList,List<ExcelErrorData> errorDatas,List<Integer> cellList) {
        List<ExcelErrorData> resultList=new ArrayList<>();
        //获取到条码规则的信息
        Map<String, Rule> ruleMap = uploadMapper.queryRule();
        //获取到单位的信息
        Map<String, Datadict> matunitMap = uploadMapper.queryType(101003);
        //物料类别信息
        Map<String, MatType> mtypeMap = uploadMapper.queryMatType();
        //物料类别名称
        Map<String, Datadict> artifactTypeIdNameMap = uploadMapper.queryType(101047);
        Map<String, Mat> matMap = uploadMapper.queryMat();
        for (int i=0;i<matList.size();i++) {
            String matCode = matList.get(i).getMatCode();

            String result = checkExcelContent(matList.get(i), matMap, ruleMap, matunitMap, mtypeMap, artifactTypeIdNameMap);
            if(!StringUtils.isEmpty(result)){
                errorDatas.add(new ExcelErrorData(cellList.get(i)+1,result));
            }
            for (int j = 1; j < i; j++) {
                //判断物料编码  物料名称是否重复
                String oldvcMatCode = com.indusfo.spc.untlis.ExcelUtil.getCellValue(sheet, cellList.get(j), 0, false);
                if (!StringUtils.isBlank(matCode) && !StringUtils.isBlank(oldvcMatCode) && oldvcMatCode.equals(matCode)) {
                    resultList.add(ExcelErrorData.getExcelErrorData(cellList.get(i), "与表格中第" + cellList.get(j) + "行存在相同物料编码"));
                    matList.remove(i);
                }
            }

        }
        return errorDatas;
    }

    /**
     * 批量新增物料
     *
     * @param matList
     * @return
     */
    @Override
    public JSONObject updateListMat(List<Mat> matList) {
        uploadMapper.updateListMat(matList);
        return null;
    }


    /**
     * 去添加查询（产品，任务单，批次 非成品）
     */
    @Override
    public JSONObject queryListMatToInsert(Mat mat) {
        try {
            //获取页面的数据个数
            Integer pagesize = mat.getPagesize();
            //获取查询的页数
            Integer pageindex = mat.getPageindex();
            if (pagesize != null && pageindex != null) {
                mat.setIncept(pagesize * (pageindex - 1));
            }
            //执行查询操作
            List<Mat> matList = matMapper.queryListMatToInsert(mat);

            //如果页数和页面数量都不为空的情况下进行计数
            if (matList.isEmpty()) {
                return JSONObject.oK(HintMessage.QUERY_NULL, matList, 0);
            } else {
                Integer count = matMapper.countMatToInsert(mat);
                return JSONObject.oK(HintMessage.QUERY_SUCCESS, matList, count);
            }

        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());

        }
    }
    /**
     * 去添加查询（产品，任务单，批次 成品）
     */
    @Override
    public JSONObject queryListMatToInsertend(Mat mat) {
        try {
            //获取页面的数据个数
            Integer pagesize = mat.getPagesize();
            //获取查询的页数
            Integer pageindex = mat.getPageindex();
            if (pagesize != null && pageindex != null) {
                mat.setIncept(pagesize * (pageindex - 1));
            }
            //执行查询操作
            List<Mat> matList = matMapper.queryListMatToInsertend(mat);

            //如果页数和页面数量都不为空的情况下进行计数
            if (matList.isEmpty()) {
                return JSONObject.oK(HintMessage.QUERY_NULL, matList, 0);
            } else {
                Integer count = matMapper.countMatToInsertend(mat);
                return JSONObject.oK(HintMessage.QUERY_SUCCESS, matList, count);
            }

        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(500, e.getMessage());

        }
    }

    @Override
    public JSONObject testQuery() {
        long start = System.currentTimeMillis();
        List<Mat> matList=matMapper.testQuery();
        int count=matMapper.countTestQuery();
        long end = System.currentTimeMillis();
        System.out.println(end-start);
        return JSONObject.oK("查询成功",matList,count);
    }
}